<script>
import { uuid } from '@/utils'
import { loadReportDayData, reportDayData } from '@/api/dayEnterpriseReporting'

export default {
  name: 'enterprise-report-day',
  data () {
    const month = this.$dayjs().format('MM')
    const total = this.$dayjs().daysInMonth()
    const columns = this.getColumns(total)
    return {
      title: `企业${month}月计量器具日数据填报表`,
      daysInMonth: total,
      submitting: false,
      loading: false,

      cols: columns,

      // 点击单元格后，正在输入的input索引
      inputIndex: -1,

      // 选中tbody里某一行tr的索引
      rowIndex: -1,

      // 日数据
      // [{uuid: string; id: string; name: string; data: number[]}]
      lists: [],
      // 计量器具列表
      // [{ id: string, name: string, serialNumber: string }]
      units: [],
    }
  },
  computed: {
    columns () {
      const columns = this.cols
      return [
        { label: '器具名称', prop: 'name', align: 'left', fixed: true, width: 200 },
        ...columns
      ]
    },
  },
  beforeDestroy () {
    this.unbindArrowKeyEvent()
  },
  mounted () {
    this.initUnits()
    this.bindArrowKeyEvent()
  },
  methods: {
    getColumns (length) {
      const letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
      const results = []
      for (let i = 0; i < length; i++) {
        let key = letters[i % letters.length]
        const j = Math.floor(i / letters.length)
        if (j > 0) {
          key = letters[j - 1] + key
        }
        results.push({
          prop: key,
          label: (i + 1) + '日',
          align: 'center',
          width: 120,
        })
      }
      return results
    },
    initUnits () {
      this.loading = true
      return loadReportDayData().then(res => {
        res.data = res.data || []
        this.lists = this.data2lists(res.data)
        this.$nextTick(() => {
          this.initInputIndex()
        })
      }).finally(() => {
        this.loading = false
      })
    },

    // 给每个input添加索引
    initInputIndex () {
      const inputs = document.querySelectorAll('.el-table__cell:not(.is-hidden) .input-cell input')
      inputs.forEach((input, index) => {
        input.dataset.inputIndex = index + ''
      })
    },

    // 单击单元格（input框）
    clickHandler (evt) {
      evt.target.select()
      this.inputIndex = Number(evt.target.dataset.inputIndex)
    },
    eventHandler (e) {
      const { key, keyCode } = e
      if (keyCode < 37 || keyCode > 40 || key.indexOf('Arrow') === -1) {
        return false
      }
      const inputs = document.querySelectorAll('.el-table__cell:not(.is-hidden) .input-cell input')
      let inputIndex = this.inputIndex
      const length = this.daysInMonth
      // ArrowUp
      if (key === 'ArrowUp' || keyCode === 38) {
        inputIndex -= length
      }
      // ArrowDown
      if (key === 'ArrowDown' || keyCode === 40) {
        inputIndex += length
      }
      // ArrowLeft
      if (key === 'ArrowLeft' || keyCode === 37) {
        inputIndex--
      }
      // ArrowRight
      if (key === 'ArrowRight' || keyCode === 39) {
        inputIndex++
      }
      if (inputIndex >= 0 && inputIndex <= inputs.length - 1) {
        this.inputIndex = inputIndex
      }
      inputs[this.inputIndex] && inputs[this.inputIndex].click()
      inputs[this.inputIndex] && inputs[this.inputIndex].scrollIntoView(false)
    },

    // 绑定方向快捷键事件
    bindArrowKeyEvent () {
      document.addEventListener('keyup', this.eventHandler, false)
    },

    // 解除绑定方向快捷键事件
    unbindArrowKeyEvent () {
      document.removeEventListener('keyup', this.eventHandler, false)
    },

    lists2data () {
      const lists = this.lists
      const cols = this.cols
      return lists.map(v => ({
        toolsNumber: v.serialNumber,
        toolsName: v.name,
        data: cols.map(vv => v[vv.prop] || null)
      }))
    },
    data2lists (data) {
      const cols = this.cols
      return data.map(v => ({
        uuid: uuid(),
        id: v.toolsNumber,
        name: v.toolsName,
        serialNumber: v.toolsNumber,
        ...cols.reduce((acc, vv, ii) => {
          acc[vv.prop] = v.data[ii] || ''
          return acc
        }, {})
      }))
    },
    saveOrUpdate () {
      const data = this.lists2data()
      this.submitting = true
      return reportDayData(data).then(() => {
        this.$message.success('上报成功')
      }).finally(() => {
        this.submitting = false
      })
    },
  }
}
</script>

<template>
 <div class="flex direction-column padding bg-white width-100 height-100" v-loading="loading">
   <h2 class="table-title text-center">
     {{title}}
     <el-button type="primary" style="float: right;" :loading="submitting" icon="el-icon-top" @click="saveOrUpdate">上报</el-button>
   </h2>

   <el-table
     class="no-padding"
    v-loading="loading" :data="lists" height="100%" border
     :header-cell-style="{
      paddingTop: '5px',
      paddingBottom: '5px',
      color: 'white',
      background: 'var(--theme-color)'
     }"
   >
     <div slot="empty" class="empty-lists">
       <i class="i-custom:search"></i>
       <span class="empty-text">暂无数据</span>
     </div>
     <el-table-column v-for="column in columns" :key="column.prop" v-bind="column">
       <template #default="{row}">
         <div v-if="column.prop !== 'name'" class="input-cell">
           <input type="text" v-model="row[column.prop]" @click="clickHandler">
         </div>
         <span v-else>{{row.name}}({{row.serialNumber}})</span>
       </template>
     </el-table-column>
   </el-table>
 </div>
</template>

<style scoped>
.no-padding ::v-deep .cell,
.no-padding ::v-deep .el-table__cell {
  padding: 0;
}
.table-title {
  margin-top: 30px;
  margin-bottom: 20px;
  font-weight: 500;
}

.input-cell input,
.input-cell {
  width: 100%;
  height: 100%;
  cursor: cell;
}
.input-cell input {
  border-color: transparent;
  outline: none;
  background: transparent;
  -webkit-appearance: none;
  display: block;
  text-align: center;
  font-size: 12px;
  padding: 5px;
  color: #333333;
  transition: all .6s;
}
.input-cell:not(.is-readonly) input:focus {
  border-color: black;
}
.is-readonly {
  background: #f6f6f6;
  overflow: hidden;
  font-size: 12px;
}
tr.is-selected .is-readonly {
  background: transparent;
}
</style>
